const { Parser } = require('acorn')
const NodeHandler = require("./nodeHandler");
const Scope = require("./scope");

class NodeIterator {
    constructor(node, scope = {}) {
        this.node = node;
        this.nodeHandler = NodeHandler;
        this.scope = scope;
    }

    traverse(node, options = {}){
        const scope = options.scope || this.scope
        const nodeIterator = new NodeIterator(node, scope)
        const _eval = this.nodeHandler[node.type]
        if (!_eval) {
            throw new Error(`canjs: Unknown node type "${node.type}".`)
        }
        return _eval(nodeIterator)
    }

    createScope (blockType = 'block') {
        return new Scope(blockType, this.scope)
    }
}

class Canjs {
    constructor (code = '', extraDeclaration = {}) {
        this.code = code
        this.extraDeclaration = extraDeclaration
        this.ast = Parser.parse(code)
        this.nodeIterator = null
        this.init()
    }

    init () {
        const globalScope = new Scope('function')
        Object.keys(this.extraDeclaration).forEach((key) => {
            globalScope.addDeclaration(key, this.extraDeclaration[key])
        })
        this.nodeIterator = new NodeIterator(null, globalScope)
    }

    run () {
        return this.nodeIterator.traverse(this.ast)
    }
}

const ws = {
    name: "wx"
}

let scriptStr = `
    let a = 1 + 1;
    console.log(a);
`

let newParser = new Canjs(scriptStr,{ws});
newParser.run();




